package com.alpha.processor.creators.interface_file;

import com.alpha.processor.processor.tools.ProcessorTool;
import com.alpha.processor.creators.base.FileCreator;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeSpec;

import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

public class ProviderInterfaceFileCreator extends FileCreator {

    private final ProviderInterfaceCreateModel createModel;

    public ProviderInterfaceFileCreator(ProcessorTool logger, Elements elementUtils, TypeElement classElement) {
        createModel = new ProviderInterfaceCreateModel(logger, elementUtils, classElement);
    }

    @Override
    public Element getClassElement() {
        return createModel.getClassElement();
    }

    @Override
    public String getFilePackageName() {
        return createModel.getPackageName();
    }

    @Override
    public String getGenerateFileName() {
        return createModel.getGenarateFileName();
    }

    @Override
    public String getGenerateFileFullName() {
        return createModel.getGenerateFileFullName();
    }

    @Override
    protected TypeSpec.Builder getClassBuilder(String className) {
        return TypeSpec.interfaceBuilder(className);
    }

    @Override
    protected void buildFile(TypeSpec.Builder fileBuilder) {
        fileBuilder.addModifiers(Modifier.PUBLIC);

        fileBuilder.addMethod(buildViewMethod());
        fileBuilder.addMethod(buildProviderMethod());
    }

    private MethodSpec buildViewMethod(){
        MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(ProviderInterfaceCreateModel.ProvideViewMethodName)
                .addModifiers(Modifier.PUBLIC)
                .addModifiers(Modifier.ABSTRACT)
                .returns(ClassName.bestGuess(createModel.getViewParamElement().asType().toString()));

        ParameterSpec.Builder paramBuilder = ParameterSpec.builder(ClassName.bestGuess(createModel.getViewClassElement().getQualifiedName().toString()),"view");
        methodBuilder.addParameter(paramBuilder.build());
        return methodBuilder.build();
    }

    private MethodSpec buildProviderMethod(){
        MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(ProviderInterfaceCreateModel.ProvideProcessorMethodName)
                .addModifiers(Modifier.PUBLIC)
                .addModifiers(Modifier.ABSTRACT)
                .returns(ClassName.bestGuess(createModel.getProcessorParamElement().asType().toString()));

        ParameterSpec.Builder paramBuilder = ParameterSpec.builder(ClassName.bestGuess(createModel.getViewClassElement().getQualifiedName().toString()),"view");
        methodBuilder.addParameter(paramBuilder.build());
        return methodBuilder.build();
    }

    public ProviderInterfaceCreateModel getCreateModel() {
        return createModel;
    }
}
